﻿using CTM.Web.Filters;
using CTM.Web.Models.Input;
using CTM.Web.Models.View.Comment;
using CTM.Web.Models.View.Conversation;
using CTM.Web.Models.View.Home;
using CTM.Web.Services;
using CTM.Web.Utils;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using System;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;

namespace CTM.Web.Controllers
{
    public class CommentController : Controller
    {
        // initialize service objects
        private IPostService postService;
        private ICommentService commentService;
        private INotificationService notificationService;
        private IAccountService accountService; // employee or user service
        private ApplicationUserManager userManager;
        public ApplicationUserManager UserManager
        {
            get
            {
                return userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
            }
            private set
            {
                userManager = value;
            }
        }

        public CommentController(IPostService postService, ICommentService commentService, INotificationService notificationService, IAccountService accountService)
        {
            this.postService = postService;
            this.commentService = commentService;
            this.notificationService = notificationService;
            this.accountService = accountService;
        }

        public ActionResult Create(Guid? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Post post = postService.GetById(id);
            if (post == null)
            {
                return HttpNotFound();
            }
            var model = new CommentViewModel
            {
                PostId = post.Id,
            };
            return PartialView(model);
        }

        [HttpPost]
        public ActionResult Create([Bind(Include = "Content,PostId")] CommentViewModel comment)
        {
            try
            {
                if (comment.PostId == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Post post = postService.GetById(comment.PostId);
                if (post == null)
                {
                    return HttpNotFound();
                }

                if (!ModelState.IsValid)
                {
                    return Json(new
                    {
                        success = false,
                        message = "An error has occurred."
                    });
                }

                var _comment = new Comment
                {
                    Id = Guid.NewGuid(),
                    Content = comment.Content,
                    CreatedBy = GlobalVariables.CurrentUser.Id,
                    CreatedOn = DateTime.UtcNow,
                    Post = post
                };

                commentService.Insert(_comment);

                #region Create notification
                                
                notificationService.Create(_comment, GlobalVariables.CurrentUser.Id);

                #endregion

                var strReply = "reply";
                if (post.Comments.Count > 0)
                {
                    strReply = post.Comments.Count + " ";
                    strReply += (post.Comments.Count > 1) ? "replies" : "reply";
                }

                return Json(new
                {
                    success = true,
                    count = strReply,
                    message = "A comment completes successfully."
                });
            }
            catch (Exception)
            {
                return Json(new
                {
                    success = false,
                    message = "An error has occurred."
                });
            }
        }

        public ActionResult Index(Guid? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Post post = postService.GetById(id);
            if (post == null)
            {
                return HttpNotFound();
            }

            var model = post.Comments.OrderBy(c => c.CreatedOn).Select(c => new CommentViewModel {
                Id = c.Id,
                Content = c.Content,
                IsDeleted = c.IsDeleted,
                CreatedOn = c.CreatedOn,
                CreatedBy = c.CreatedBy,
                ModifiedOn = c.ModifiedOn,
                ModifiedBy = c.ModifiedBy,
                CreatedUser = UserManager.FindById(c.CreatedBy),
                ModifiedUser = UserManager.FindById(c.ModifiedBy)
            });

            return PartialView(model.ToList());
        }

        // GET: Comment/Delete/5
        public ActionResult Delete(Guid? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Comment comment = commentService.GetById(id);
            if (comment == null)
            {
                return HttpNotFound();
            }
            var model = new CommentViewModel(comment);
            if (Request.IsAjaxRequest())
                return PartialView(model);
            return View(model);
        }

        // POST: Comment/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(Guid id)
        {
            Comment comment = commentService.GetById(id);

            // delete notifications
            foreach (var notification in comment.Notifications)
            {
                notification.IsDeleted = true;
            }

            comment.IsDeleted = true;
            comment.ModifiedOn = DateTime.UtcNow;
            comment.ModifiedBy = GlobalVariables.CurrentUser.Id;

            commentService.Update(comment);
            return RedirectToAction("Index", new { id = comment.Post.Id });
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (userManager != null)
                {
                    userManager.Dispose();
                    userManager = null;
                }               
            }

            base.Dispose(disposing);
        }
    }
}